package com.atguigu.dga;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created by Smexy on 2023/11/3
 *
    线程：  Thread
        如何启动: Thread.start()

    线程执行的任务:
            用户自己去定义。
            定义完了以后，把线程执行的任务，传入到线程中，让线程执行。
            举例:
                    main线程要执行的任务，通过main()来编写。

    如何定义线程执行的任务?
      方式一:继承 Thread，重写run()
      方式二:java是单继承的，extends关键字很珍贵
            不要使用extends 来继承线程。
            实现Runable接口
            1.0 古老
      方式三: Callable
            对比Runnable，可以抛异常，可以返回数据。
            1.5 古老



 */
public class ThreadDemo
{
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        MyThreadTask myThreadTask = new MyThreadTask();
        myThreadTask.start();
        System.out.println(Thread.currentThread().getName()+"   main");

        //Runable
        MyThreadTask2 task2 = new MyThreadTask2();
        new Thread(task2).start();

        //Callable
        MyThreadTask3 task3 = new MyThreadTask3();
        //帮你接收Callable任务类返回的数据
        FutureTask<String> futureTask = new FutureTask<>(task3);
        new Thread(futureTask).start();

        //get()会阻塞当前线程
        System.out.println("任务返回的结果:"+futureTask.get());
        System.out.println(Thread.currentThread().getName()+"   main.....");

    }
}

class MyThreadTask extends Thread{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"  aaaa");
    }
}

class MyThreadTask2 implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"  bbbb");
    }
}

class MyThreadTask3 implements Callable<String>
{
    @Override
    public String call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"  cccc");
        Thread.sleep(5000);
        return "ok";
    }
}
